package proxy

import (
	"fmt"
	"net"
	"net/http"

	mysqlproxy "gitee.com/xuender/mysql-proxy"
	"gitee.com/xuender/mysql-proxy/pb"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/xelabs/go-mysqlstack/driver"
	"github.com/xelabs/go-mysqlstack/xlog"
	"github.com/xuender/oils/base"
	"github.com/xuender/oils/gins"
	"github.com/xuender/oils/logs"
	"github.com/xuender/oils/oss"
)

type Service struct {
	c  *pb.Config
	ds *DBService
	as *AuthService
	cs *ConnService
	os *ConfigService
}

func NewService(
	config *pb.Config,
	dbService *DBService,
	authService *AuthService,
	connService *ConnService,
	configService *ConfigService,
) *Service {
	return &Service{
		c:  config,
		ds: dbService,
		as: authService,
		cs: connService,
		os: configService,
	}
}

func (p *Service) Run() {
	log := xlog.NewStdLog(xlog.Level(xlog.INFO))
	mysqld := base.Panic1(driver.MockMysqlServerWithPort(log, int(p.c.Port), p.ds))

	defer mysqld.Close()

	logs.Infow("启动", "mysql", mysqld.Addr(), "web", p.c.WebPort)

	engine := gins.New()
	store := cookie.NewStore([]byte("secret"))
	engine.Use(sessions.Sessions("session", store))
	engine.Use(StaticHandler("/", mysqlproxy.WWW, "www"))

	api := engine.Group("/api")
	api.GET("/", p.ping)

	p.as.Group(api.Group("/auth"))
	p.cs.Group(api.Group("/conn", p.as.Hander))
	p.os.Group(api.Group("/config", p.as.Hander))

	lister := base.Panic1(net.Listen("tcp", fmt.Sprintf(":%d", p.c.WebPort)))
	oss.SignalClose(p, lister)
	_ = engine.RunListener(lister)

	logs.Info("退出")
}

func (p *Service) Error(err error) {
	logs.Error(err)
}

func (p *Service) ping(ctx *gin.Context) {
	session := sessions.Default(ctx)

	logs.Debugw("ping", gin.AuthUserKey, session.Get(gin.AuthUserKey))

	ctx.JSON(http.StatusOK, "pong")
}
